//----------------------------------------------------------------------------
//  ,-.
// /_\___ ,   Ninja Framework
// '  ___\    (C) Riccardo Capra - http://riccar.do
//  //   \\
//----------------------------------------------------------------------------
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

#include "NjNinjaSync.h"
#include "NjRefObject.h"

//----------------------------------------------------------------------------
NjRefObject::~NjRefObject()
{
#if NJ_REFERENCE_COUNTER_DEBUG
#	if NJ_ASSERT_ENABLED
	NjUint const uCounter(GetReferenceCounterDebug());
	NjUint const uTotInstances=
#	endif // NJ_ASSERT_ENABLED

	ms_kTotalInstancesDebug.PostDecrement();

	NJ_ASSERT(uCounter==0);
	NJ_ASSERT(uTotInstances>0);
#endif // NJ_REFERENCE_COUNTER_DEBUG
}
//----------------------------------------------------------------------------
NjBool NjRefObject::TryDecrementReference()
{
	NjUint uCounter(m_kCounter.Get());

	for(;;)
	{
		NJ_ASSERT(uCounter>0);

		if (uCounter==1)
			return NJ_FALSE;

		NjUint const uOldCounter(m_kCounter.PostCompareExchange(uCounter, uCounter-1));

		if (uOldCounter==uCounter)
			return NJ_TRUE;

		uCounter=uOldCounter;
	}
}
//----------------------------------------------------------------------------
NjBool NjRefObject::OnDispose()
{
	return NJ_TRUE;
}
//----------------------------------------------------------------------------
void NjRefObject::Dispose()
{
	if (!OnDispose())
		return;

	NjDelete(this);
}
//----------------------------------------------------------------------------
#if NJ_REFERENCE_COUNTER_DEBUG
NjAtomic<NjUint> NjRefObject::ms_kTotalInstancesDebug(0);
#endif // NJ_REFERENCE_COUNTER_DEBUG
//----------------------------------------------------------------------------
